package com.s2paganini.tween 
{
	import flash.display.DisplayObject;
	import flash.events.TimerEvent;
	import flash.filters.BlurFilter;
	import flash.utils.Timer;

	/**
	 * @author siLvio paganini | s2paganini.com
	 * @purpose Shakes the Display Object
	 */
	public class Shake 
	{
		public static const SHAKE_HORIZONTAL : String = "shakeHor";
		public static const SHAKE_VERTICAL : String = "shakeVer";
		public static const SHAKE_BOTH : String = "shakeBoth";
		
		private static var timer : Timer;
		private static var objectToShake : DisplayObject;
		private static var functionToApply : Function;
		private static var delay : Number = 0;
		private static var timerStart : Timer;
		private static var functionParams : Array;
		private static var interval : Number = 30;
		private static var initX : Number;
		private static var initY : Number;
		private static var counter : int;
		private static var counter2 : int;
		private static var direction : String = SHAKE_BOTH;

		/**
		 * <b>Parameters</b><br>
		 * @param obj DisplayObject to tween
		 * @param time Time that the object will shake
		 * @param delay Delay to start Tweening ((<b>Default : 0</b>)
		 * @param interval Interval between each blink in milliseconds (<b>Default : 30</b>)
		 * @param onComplete function to call after Tween ends
		 * @param onCompleteParams Array of params of the onComplete function
		 * 
		 * @usage
		 * Shake.addShake(test, .5, {direction: Shake.SHAKE_BOTH, onComplete: functionOnComplete});
		 */
		public static function addShake(obj : DisplayObject, time : Number, p_param : Object = null) : void
		{
			objectToShake = obj;
			functionParams = new Array();
			
			initX = objectToShake.x;
			initY = objectToShake.y;
			
			counter = 0;
			counter2 = 0;
			
			if(p_param) {
				functionToApply = (p_param["onComplete"] == null) ? null : p_param["onComplete"];
				functionParams = (p_param["onCompleteParams"] == null) ? null : p_param["onCompleteParams"];
				delay = (p_param["delay"] == null) ? 0 : p_param["delay"];
				interval = (p_param["interval"] == null) ? 30 : p_param["interval"];
				direction = (p_param["direction"] == null) ? SHAKE_BOTH : p_param["direction"];
			}
			
			timer = new Timer(interval, time * interval);
			timer.addEventListener(TimerEvent.TIMER, listenerTimer);
			timer.addEventListener(TimerEvent.TIMER_COMPLETE, listenerTimer);
			
			timerStart = new Timer(delay * 1000, 1);
			timerStart.addEventListener(TimerEvent.TIMER_COMPLETE, listenerTimerStart);
			timerStart.start();
		}
		
		public static function killShake() : void{
			timer.stop();
			objectToShake.x = initX;
			objectToShake.y = initY;
		}

		private static function listenerTimerStart(event : TimerEvent) : void
		{
			objectToShake.filters = [new BlurFilter(5, 5)];
			timerStart.removeEventListener(TimerEvent.TIMER_COMPLETE, listenerTimerStart);
			timer.start();
		}

		private static function listenerTimer(event : TimerEvent) : void
		{
			switch(event.type) {
				case "timer":
					objectToShake.y = initY;
					objectToShake.x = initX;
					shakeIt();
					break;
				
				case "timerComplete":
					timer.removeEventListener(TimerEvent.TIMER, listenerTimer);
					timer.removeEventListener(TimerEvent.TIMER_COMPLETE, listenerTimer);
					
					if(functionToApply != null)	functionToApply.apply(null, functionParams);
					
					objectToShake.filters = [new BlurFilter(0, 0)];
					objectToShake.x = initX;
					objectToShake.y = initY;
					
					counter = 0;
					counter2 = 0;
					break;	
			}
		}

		private static function shakeIt() : void
		{
			if(direction == SHAKE_BOTH) {
				if(counter % 2 == 0) {
					objectToShake.x = counter2 % 2 == 0 ? initX + 5 : initX - 5;					
					counter2++;
				} else {
					if(counter2 % 2 == 0) {
						objectToShake.y = counter2 % 2 == 0 ? initY + 5 : initY - 5;				
					}
				}
				counter++;
				
			} else if(direction == SHAKE_HORIZONTAL) {
				objectToShake.x = counter % 2 == 0 ? initX + 5 : initX - 5;
				counter++;
			} else {
				objectToShake.y = counter2 % 2 == 0 ? initY + 5 : initY - 5;
				counter2++;
			}
		}
	}
}
